﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace Serializer
{
    public static class MessageObjectSerializer
    {
        /// <summary>
        /// Convert an object to a byte array
        /// </summary>
        /// <typeparam name="T">Object type</typeparam>
        /// <param name="obj">Object to serialize</param>
        /// <returns>Serialized object in byte array</returns>
        public static byte[] Serialize<T>(T obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            byte[] bytes = null;

            using (MemoryStream ms = new MemoryStream())
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(T));

                using (XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms))
                {
                    serializer.WriteObject(binaryDictionaryWriter, obj);
                }

                bytes = ms.ToArray();
            }

            return bytes;
        }

        /// <summary>
        /// Convert a byte array to an object
        /// </summary>
        /// <typeparam name="T">Object type</typeparam>
        /// <param name="bytes">Serialized object in byte array</param>
        /// <returns>Deserialized object</returns>
        public static T Deserialize<T>(byte[] bytes)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            T obj;

            using (MemoryStream memStream = new MemoryStream())
            {
                memStream.Write(bytes, 0, bytes.Length);
                memStream.Seek(0, SeekOrigin.Begin);
                DataContractSerializer serializer = new DataContractSerializer(typeof(T));

                using (XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateBinaryReader(memStream, XmlDictionaryReaderQuotas.Max))
                {
                    obj = (T)serializer.ReadObject(binaryDictionaryReader);
                }
            }

            return obj;
        }
    }
}
